﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;

namespace HYRElectric.WirePlace
{
	[Regeneration(RegenerationOption.Manual)]
	[Transaction(TransactionMode.Manual)]
	public class CmdCreateConduitByWire : YJKCommandAuto
	{
		protected override Result YJKExcute(ExternalCommandData cmdData, ref string message, ElementSet elements)
		{
			UIDocument activeUIDocument = cmdData.Application.ActiveUIDocument;
			Document document = activeUIDocument.ActiveView.Document;
			Selection selection = activeUIDocument.Selection;
			Level genLevel = activeUIDocument.ActiveView.Document.ActiveView.GenLevel;
			using (this.dlgcreate = new DlgCreateConduitByWire(document))
			{
				try
				{
                    if (this.dlgcreate.ResultDlg == Result.Failed)
					{
						return Autodesk.Revit.UI.Result.Failed;
					}
					DialogResult dialogResult = this.dlgcreate.ShowDialog();
					if (dialogResult == DialogResult.Cancel)
					{
						return Autodesk.Revit.UI.Result.Cancelled;
					}
					if (dialogResult == DialogResult.OK)
					{
						this.conduitType = (this.dlgcreate.cbxConduitType.SelectedItem as ConduitType);
						this.height = genLevel.Elevation + AssistFunc.mmToFeet(Convert.ToDouble(this.dlgcreate.txtHeight.Text));
						this.symbo = (this.dlgcreate.cbxElbowFittingType.SelectedItem as FamilySymbol);
						this.material = this.dlgcreate.cbxConduitMaterial.SelectedItem.ToString();
						this.diameter = this.dlgcreate.cbxConduitDiameter.SelectedItem.ToString();
						Category category = document.Settings.Categories.get_Item(BuiltInCategory.OST_Conduit);
						document.ActiveView.SetYJKVisibility(category, true);
						for (;;)
						{
							Reference reference = selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new ElectricDim.WireFilter(), "请选择要过滤选择的导线");
							this.currentWire = (document.GetElement(reference) as Wire);
							this.DeleteExistConduit(document, this.currentWire);
							this.wireList.Add(this.currentWire);
							ElementSet elementSet = activeUIDocument.Application.Application.Create.NewElementSet();
							elementSet.Insert(this.currentWire);
							activeUIDocument.Document.ActiveView.HideYJKElements(elementSet);
							LocationCurve locationCurve = this.currentWire.Location as LocationCurve;
							XYZ hyendPoint = locationCurve.Curve.GetEndPoint(0);
							XYZ hyendPoint2 = locationCurve.Curve.GetEndPoint(1);
							Conduit conduit = Conduit.Create(document, this.conduitType.Id, new XYZ(hyendPoint.X, hyendPoint.Y, this.height), new XYZ(hyendPoint2.X, hyendPoint2.Y, this.height), genLevel.Id);
							RevitVersionFuncs.AddToSelection(selection, conduit);
							List<Connector> conduitConnectors = this.GetConduitConnectors(conduit);
							if (conduitConnectors == null || conduitConnectors.Count != 2)
							{
								break;
							}
							LocationCurve locationCurve2 = conduit.Location as LocationCurve;
							XYZ hyendPoint3 = locationCurve2.Curve.GetEndPoint(0);
							XYZ hyendPoint4 = locationCurve2.Curve.GetEndPoint(1);
							this.GetDefaultElbow(document, conduit);
							this.SetConduitSharePara(document, conduit);
							ConnectorSet unusedConnectors = this.currentWire.ConnectorManager.UnusedConnectors;
							if (unusedConnectors == null || unusedConnectors.IsEmpty)
							{
								List<Connector> equConnector = this.GetEquConnector(this.currentWire);
								if (equConnector != null && equConnector.Count > 0 && equConnector.Count<Connector>() == 2)
								{
									Connector connector = null;
									Connector connector2 = null;
									foreach (Connector connector3 in equConnector)
									{
										if (connector3.Origin.IsAlmostEqualTo(hyendPoint))
										{
											connector = connector3;
										}
										else
										{
											connector2 = connector3;
										}
									}
									try
									{
										Conduit conduit2 = Conduit.Create(document, this.conduitType.Id, hyendPoint3, connector.Origin, genLevel.Id);
										List<Connector> conduitConnectors2 = this.GetConduitConnectors(conduit2);
										this.GetDefaultElbow(document, conduit2);
										this.SetConduitSharePara(document, conduit2);
										FamilyInstance familyInstance = this.m_doc.Create.NewElbowFitting(conduitConnectors2[0], conduitConnectors[0]);
										if (this.dlgcreate.ClickEx == 1)
										{
											familyInstance.Symbol = this.symbo;
										}
									}
									catch (Exception)
									{
									}
									try
									{
										Conduit conduit3 = Conduit.Create(document, this.conduitType.Id, hyendPoint4, connector2.Origin, genLevel.Id);
										List<Connector> conduitConnectors3 = this.GetConduitConnectors(conduit3);
										this.GetDefaultElbow(document, conduit3);
										this.SetConduitSharePara(document, conduit3);
										FamilyInstance familyInstance2 = this.m_doc.Create.NewElbowFitting(conduitConnectors3[0], conduitConnectors[1]);
										if (this.dlgcreate.ClickEx == 1)
										{
											familyInstance2.Symbol = this.symbo;
										}
										continue;
									}
									catch (Exception)
									{
										continue;
									}
									goto IL_444;
								}
							}
						}
						MessageBox.Show("导线生成线管失败", "盈建科提示");
						return Autodesk.Revit.UI.Result.Failed;
					}
					IL_444:;
				}
				catch (Exception)
				{
				}
			}
			ElementSet elementSet2 = new ElementSet();
			foreach (Wire wire in this.wireList)
			{
				elementSet2.Insert(wire);
			}
			if (elementSet2.Size > 0)
			{
				cmdData.Application.ActiveUIDocument.Document.ActiveView.UnHideYJKElements(elementSet2);
			}
			return base.YJKExcute(cmdData, ref message, elements);
		}

		private void DeleteExistConduit(Document doc, Wire wire)
		{
			List<Conduit> list = new List<Conduit>();
			List<ElementId> list2 = new List<ElementId>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Conduit)).ToElements())
			{
				Conduit conduit = element as Conduit;
				try
				{
					if (conduit.GetParameter("所含导线").AsString() == wire.Id.ToString() && !list2.Contains(conduit.Id))
					{
						list.Add(conduit);
						list2.Add(conduit.Id);
					}
				}
				catch (Exception)
				{
				}
			}
			List<ElementId> list3 = new List<ElementId>();
			foreach (MEPCurve mepcurve in list)
			{
				List<Connector> list4 = new List<Connector>();
				ConnectorSetIterator connectorSetIterator = mepcurve.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector item = obj as Connector;
					list4.Add(item);
				}
				foreach (Connector connector in list4)
				{
					ConnectorSet allRefs = connector.AllRefs;
					if (allRefs.Size > 0)
					{
						foreach (object obj2 in allRefs)
						{
							Element owner = ((Connector)obj2).Owner;
							if (owner is FamilyInstance && !list3.Contains(owner.Id))
							{
								list3.Add(owner.Id);
							}
						}
					}
				}
			}
			if (list2.Count > 0)
			{
				doc.Delete(list2);
			}
			if (list3.Count > 0)
			{
				doc.Delete(list3);
			}
		}

		private List<Connector> GetConduitConnectors(Conduit conduit)
		{
			List<Connector> list = new List<Connector>();
			Connector item = null;
			Connector item2 = null;
			XYZ hyendPoint = (conduit.Location as LocationCurve).Curve.GetEndPoint(0);
			ConnectorSetIterator connectorSetIterator = conduit.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector item3 = obj as Connector;
				list.Add(item3);
			}
			foreach (Connector connector in list)
			{
				if (connector.Origin.IsAlmostEqualTo(hyendPoint))
				{
					item = connector;
				}
				else
				{
					item2 = connector;
				}
			}
			list.Clear();
			list.Add(item);
			list.Add(item2);
			return list;
		}

		private void SetConduitSharePara(Document doc, Conduit conduit)
		{
			Dictionary<string, ParameterType> dictionary = new Dictionary<string, ParameterType>();
            dictionary.Add("材质", (ParameterType)1);
            dictionary.Add("管径", (ParameterType)143);
            dictionary.Add("所含导线", (ParameterType)1);
			foreach (KeyValuePair<string, ParameterType> keyValuePair in dictionary)
			{
				if (conduit.GetParameter(keyValuePair.Key) == null)
				{
					YArchitech.Revit.Electric.Common.SharedParameter.InsertSharedParameter(doc, BuiltInCategory.OST_Conduit, "电气数据", dictionary, true);
					break;
				}
			}
			conduit.GetParameter("材质").Set(this.material);
			conduit.GetParameter("管径").Set(AssistFunc.mmToFeet(Convert.ToDouble(this.diameter)));
			conduit.GetParameter("所含导线").Set(this.currentWire.Id.ToString());
		}

		private void GetDefaultElbow(Document doc, Conduit conduit)
		{
			ConduitType conduitType = doc.GetElementById(conduit.GetTypeId()) as ConduitType;
			if (conduitType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_BEND_PARAM).AsElementId().ToString() == "-1" && this.dlgcreate.DefaultValue.Count > 0)
			{
				conduitType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_BEND_PARAM).Set(this.dlgcreate.DefaultValue[0]);
			}
		}

		private List<Connector> GetEquConnector(Wire wire)
		{
			List<Connector> list = new List<Connector>();
			List<Connector> list2 = new List<Connector>();
			ConnectorSetIterator connectorSetIterator = wire.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector item = obj as Connector;
				list2.Add(item);
			}
			List<Element> list3 = new List<Element>();
			foreach (Connector connector in list2)
			{
				ConnectorSet allRefs = connector.AllRefs;
				if (allRefs.Size > 0)
				{
					foreach (object obj2 in allRefs)
					{
						Element owner = ((Connector)obj2).Owner;
						if (owner is FamilyInstance && !list3.Contains(owner))
						{
							list3.Add(owner);
						}
					}
				}
			}
			foreach (Element element in list3)
			{
				ConnectorSetIterator connectorSetIterator2 = (element as FamilyInstance).MEPModel.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator2.MoveNext())
				{
					object obj3 = connectorSetIterator2.Current;
					Connector connector2 = obj3 as Connector;
					if (connector2.Domain == (Autodesk.Revit.DB.Domain)2)
					{
						list.Add(connector2);
					}
				}
			}
			return list;
		}

		private Wire currentWire;

		private ConduitType conduitType;

		private FamilySymbol symbo;

		private string material;

		private string diameter;

		private double height;

		private List<Wire> wireList = new List<Wire>();

		private DlgCreateConduitByWire dlgcreate;
	}
}
